Skip to content

fix(desktop): show invocable relay-directory agents in mention/add gate [HIV-13]#1

Merged
jjgarciarovira merged 1 commit into
mainfrom
fix/agent-mention-gate-invocable-relay-agents
Jul 25, 2026
Merged

fix(desktop): show invocable relay-directory agents in mention/add gate [HIV-13]#1
jjgarciarovira merged 1 commit into
mainfrom
fix/agent-mention-gate-invocable-relay-agents

Conversation

@jjgarciarovira

Copy link
Copy Markdown

Summary

Relay-directory agents that are invocable and shared with the viewer were being hidden from both mention autocomplete and the add-members picker. This restores them while preserving PR block#2149's dedup/ranking intent.

Linear: HIV-13

⚠️ Do not merge yet. This touches the shared agent-autocomplete gate in Q's primary repo. Please leave open for JJ + Q review. Agents will not merge this.

Problem

A "box-run resident" agent — a NIP-OA-badged agent that runs on a shared relay — is invisible in the desktop client:

  • It cannot be @-mentioned (mention autocomplete never lists it).
  • It cannot be added to a channel via the members picker (it never appears under "Not in this channel").

This happens even when the agent has a valid owner-auth tag in its kind:0 (so isAgent === true) and a proper kind:10100 relay-directory card with respond_to: "anyone" and shared channel_ids — i.e. it is genuinely invocable by the viewer.

Root cause

PR block#2149 (a4dfead2) introduced isAgentIdentityInManagedList and applied it as an eligibility gate in two places:

  • desktop/src/features/messages/lib/useMentions.ts:249 — mention autocomplete candidate builder.
  • desktop/src/features/channels/ui/MembersSidebar.tsx:273 — add-members search-result builder.

The original gate drops any candidate flagged isAgent whose pubkey is not in the viewer's local managed-agents list:

candidate.isAgent !== true ||
managedAgentPubkeys.has(normalizePubkey(candidate.pubkey))

Box-run resident agents are isAgent === true (valid owner-auth badge) but are never in any single viewer's local managed list — they live on the relay, not on the viewer's machine. So the gate rejected them.

Note that the sibling gate shouldHideAgentFromMentions (agentAutocompleteEligibility.ts) already handled invocability correctly via mentionableAgentPubkeys; only isAgentIdentityInManagedList was too narrow, so it short-circuited the candidate before the invocability logic ever ran.

The change — two admission paths

isAgentIdentityInManagedList(candidate, managedAgentPubkeys, mentionableAgentPubkeys) now admits a non-agent candidate unconditionally, and admits an agent candidate when its normalized pubkey is in either set:

  1. managedAgentPubkeys — agents the viewer manages locally. This is the original fix(desktop): prefer live agent mentions block/buzz#2149 path: a bare isAgent badge with no relationship is still not enough on its own.
  2. mentionableAgentPubkeys — agents the viewer can actually invoke: locally-managed ∪ relay-directory (kind:10100) agents shared with the viewer (respond_to: "anyone" in a shared channel, or an allowlist that includes the viewer). This is the same set already produced by getMentionableAgentPubkeys and consumed by shouldHideAgentFromMentions.

Because a candidate still needs to be reachable through one of these two paths, a bare agent badge with no directory relationship is still droppedblock#2149's dedup/ranking behavior is unchanged; this only restores agents the viewer can legitimately invoke.

Wiring:

  • useMentions.ts passes the mentionableAgentPubkeys memo it already computes (no new query).
  • MembersSidebar.tsx builds the same set locally via useChannelsQuery + getMentionableAgentPubkeys / getSharedChannelIds, using the component's existing currentPubkey, relayAgentsQuery, and managedAgentsQuery.

Test coverage

desktop/src/features/agents/lib/agentAutocompleteEligibility.test.mjs:

  • new admits invocable relay agents via the mentionable set — covers (a) an isAgent candidate in the mentionable-but-not-managed set is admitted (incl. mixed-case pubkey normalization), (b) an isAgent candidate in neither set is dropped, and (c) a non-agent is unaffected.
  • updated keeps people and only current managed agent identities for the new three-arg arity (managed-only behavior verified with an empty mentionable set).

Checks run against the desktop TS surface (what CI's desktop-check / desktop-typecheck / desktop-test run):

  • pnpm check (biome + file-size + px-text + pubkey-truncation guards) — pass
  • pnpm typecheck (tsc --noEmit) — pass
  • pnpm test3372 pass, 0 fail (19 in the eligibility suite)

useMentions.ts sat exactly at the 1000-line size guard, so the necessary +6 lines were reclaimed within the same file by folding the single-use sharedChannelIds memo into mentionableAgentPubkeys and compacting the adjacent personaNameByPubkey memo (both behavior-preserving; file is now 998 lines).

Rollout note

This is a desktop client-side change only — no relay/protocol change. Users must rebuild / update the desktop app to pick it up; already-running installs will keep hiding these agents until updated.

Review

  • Repo: 3442labs/buzz (Q's primary repo). Upstreamable to block/buzz later.
  • Reviewers: JJ + Q.
  • Leave open — do not merge.

…te [HIV-13]

PR block#2149 (a4dfead) added `isAgentIdentityInManagedList`, which drops any
candidate flagged `isAgent` whose pubkey is not in the viewer's LOCAL
managed-agents list. That gate runs in mention autocomplete (useMentions)
and the add-members picker (MembersSidebar).

The gate is too narrow for box-run resident agents: NIP-OA-badged agents
that run on a shared relay get `isAgent=true` from a valid owner-auth tag
in their kind:0, and advertise a proper kind:10100 directory card with
respond_to:"anyone" and shared channel_ids. They are legitimately
invocable by the viewer, but they never appear in any single viewer's
local managed list, so block#2149 made them invisible to both mention and add.

Widen the gate to admit an agent candidate when its normalized pubkey is
in EITHER the locally-managed set OR the mentionable set (locally-managed
union relay-directory agents shared with the viewer, as already computed
by getMentionableAgentPubkeys and used by shouldHideAgentFromMentions). A
bare agent badge with no directory relationship is still dropped, so
block#2149's dedup/ranking intent is preserved -- this only restores agents the
viewer can actually invoke.

- eligibility: isAgentIdentityInManagedList takes the mentionable set as a
  third arg and admits via either set.
- useMentions: pass the mentionableAgentPubkeys it already computes.
- MembersSidebar: build the same set (useChannelsQuery +
  getMentionableAgentPubkeys/getSharedChannelIds) and pass it.
- tests: cover invocable-relay-agent admission and the neither-set drop;
  update existing call-site tests for the new arity.

useMentions memos were tightened (folded the single-use sharedChannelIds
memo, compacted personaNameByPubkey) to keep the file within the
1000-line size guard.
@jjgarciarovira
jjgarciarovira merged commit fe53583 into main Jul 25, 2026
@jjgarciarovira
jjgarciarovira deleted the fix/agent-mention-gate-invocable-relay-agents branch July 25, 2026 01:44
jjgarciarovira added a commit that referenced this pull request Jul 25, 2026
…vocable-relay-agents"

This reverts commit fe53583, reversing
changes made to f8fd055.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant